package org.xbrlapi.data.bdbxml.examples.tests;


import java.net.URI;
import java.sql.Date;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.List;
import java.util.SortedSet;

import org.apache.log4j.Logger;
import org.testng.Assert;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import org.w3c.dom.Element;
import org.xbrlapi.Arc;
import org.xbrlapi.Concept;
import org.xbrlapi.Context;
import org.xbrlapi.Instance;
import org.xbrlapi.Item;
import org.xbrlapi.LabelResource;
import org.xbrlapi.Period;
import org.xbrlapi.Relationship;
import org.xbrlapi.data.Store;
import org.xbrlapi.impl.SimpleNumericItemImpl;
import org.xbrlapi.loader.Loader;
import org.xbrlapi.networks.AnalyserImpl;
import org.xbrlapi.utilities.Constants;
import org.xbrlapi.utilities.XBRLException;

/**
 * @author Geoffrey Shuetrim (geoff@galexy.net)
 */
public class Pavel2TestCase extends BaseTestCase {


    private static final URI uri = URI.create("http://pavel.com/rop-20120331.xml");
    // Create the logger
    protected static Logger logger = Logger.getLogger(LoadTestCase.class);
    private Store store = null;
    private Loader loader = null;

    @BeforeMethod
    protected void setUp() throws Exception {
        super.setUp();
        store = createStore("pavel2");
        store.setAnalyser(new AnalyserImpl(store));
        loader = createLoader(store);
    }

    @AfterMethod
    protected void tearDown() throws Exception {
        super.tearDown();
/*        try {
            if (store!= null) store.delete();
        } catch (Exception x) {
            Assert.fail("The store could not be deleted.");
        }
*/
    }

    /**
     * Test table construction
     */
    @Test
    public void testLoadingOfPavelData() {
        try {

            loader.discover(uri);

            List<Instance> instances = store.getFragmentsFromDocument(uri, "Instance");
            for (Instance instance : instances) {
                logger.info("XBRL Instance: " + instance.getURI());
                getTables(instance, store);
            }

        } catch (Exception e) {
            Assert.fail("Unexpected: " + e.getMessage());
        }
    }

    private void getTables(Instance instance, Store store) throws XBRLException, ParseException {

        List<Context> allContexts = instance.getContexts();

        logger.info("# contexts = " + allContexts.size());

        for (Context context : allContexts) {
            System.out.println("Processing context with ID:" + context.getId());

            final int columnIndex = 1;

            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

            Period period = context.getPeriod();
            if (!period.isInstantPeriod()) {
                String start = period.getStart();
                String end = period.getEnd();

                Date startDate = new Date(sdf.parse(start).getTime());
                Date endDate = new Date(sdf.parse(end).getTime());

                // logger.info("Created PeriodColumn with end:" + end +
                // " start:" + start);

            } else {
                String instant = period.getInstant();
                Date endDate = new Date(sdf.parse(instant).getTime());

                //logger.info("Created InstantColumn with end:" + endDate );
            }

            List<Item> items = context.getReferencingItems();
            //logger.info("# items for context = " + items.size());


            int x = 0;

            for (Item item : items) {

                if (item instanceof SimpleNumericItemImpl) {

                    SimpleNumericItemImpl itemImpl = (SimpleNumericItemImpl) item;

                    String stringValue = itemImpl.getValue();
                    String name = itemImpl.getLocalname();

                    Element element = itemImpl.getDataRootElement();
                    String nodeName = element.getNodeName(); // this is the name!
                    nodeName = nodeName.replaceAll(":", "_");

                    Double value = Double.valueOf(stringValue);

                    Concept concept = itemImpl.getConcept();
                    List<LabelResource> lrs = concept.getLabels();
                    logger.info("# labels = " + lrs.size());
                    // As I don't know how to connect concept to labels via network builder I try to get something from the persisted data

                    String arcRole = Constants.PresentationArcrole;

                    for (LabelResource lr : lrs) {

                        SortedSet<Relationship> relationships = store.getRelationshipsFrom(concept.getIndex(), lr.getResourceRole(), arcRole);

                        logger.info("# relationships = " + relationships.size());

                        for (Relationship relationship : relationships) {
                            Arc arc = relationship.getArc();
                            String labelRole = Constants.StandardLabelRole;
                            if (arc.hasAttribute("preferredLabel")) {
                                String preferredLabelRole = arc.getAttribute("preferredLabel");
                                labelRole = preferredLabelRole;
                            }

                            Double order = arc.getOrder();
                            if (order != null) {
                                System.out.println("Order found.");
                            }
                            String key = lr.getStringValue();

                            // this is what I need, ordered keys
                            System.out.println(key + ":" + order);
                        }
                    }
                    x++;
                }
            }
        }
    }

}